package ws.very.android.util.async.askbox;

import ws.very.util.lang.function.Fn;

public class AskBox<T> {

	private EventsBox<Object> box = new EventsBox<Object>();

	public AskBox() {
		super();

	}

	Boolean isRight;

	protected void complete(Object v) {
		box.complete(v);
	}

	public synchronized void result(T t) {
		if(isRight!=null) return;
		isRight = true;
		complete(t);
	}

	public synchronized void ex(Throwable t) {
		if(isRight!=null) return;
		isRight = false;
		complete(t);
	}

	public <S> AskBox<S> map(final Fn<T, S> mapfn) {
		final AskBox<S> askBox = new AskBox<S>();
		onResult(new Fn<T, Void>() {

			@Override
			public Void apply(T in) {
				askBox.result(mapfn.apply(in));
				return null;
			}

		});
		onEx(new Fn<Throwable, Void>() {

			@Override
			public Void apply(Throwable in) {
				askBox.ex(in);
				return null;
			}

		});

		return askBox;
	}

	public  AskBox<T> onResult(final Fn<T, Void> r) {
		box.onComplete(new Fn<Object, Void>() {

			@Override
			public Void apply(Object in) {
				if (isRight)
					r.apply((T) in);
				return null;
			}
		});
		return this;
	}

	public  AskBox<T> onEx(final Fn<Throwable, Void> r) {
		box.onComplete(new Fn<Object, Void>() {

			@Override
			public Void apply(Object in) {
				if (!isRight)
					r.apply((Throwable) in);
				return null;
			}

		});
		return this;
	}

}
